package com.csaba.connector.fhb.model;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import com.csaba.connector.ServiceException;
import com.csaba.connector.fhb.FHBLoginService;
import com.csaba.connector.fhb.FHBLogoutService;
import com.csaba.connector.model.Customer;
import com.csaba.connector.service.LoginService;
import com.csaba.connector.service.LogoutService;
import com.csaba.connector.web.util.SpecialHttpClient;
import com.csaba.connector.web.util.WebSession;
import com.csaba.util.LoggerHelper;

public class FHBSession extends WebSession
{
	private final static Logger logger = LoggerHelper.getDefaultLogger();

	private static final long serialVersionUID = -4782089416454073619L;

	public final static boolean DUMP_TEXT = false;
	public final static boolean DEBUG_FILE = true;
	public final static String DEBUG_FILE_PATH = "../fhb.source/";

	private String csrfToken = null;

	public FHBSession()
	{
		super();
		setBank(FHBBank.getInstance());
		if ( DEBUG_FILE )
			setDebugFilePath(DEBUG_FILE_PATH);
		setDumpText(DUMP_TEXT);
		setDummyInterval(30);
	}

	@Override
	protected DefaultHttpClient initHttpClient()
	{
		return new SpecialHttpClient(SpecialHttpClient.CERT_NETLOCK_A);
	}

	@Override
	protected String execute( final HttpRequestBase request ) throws ServiceException
	{
		final String result = super.execute(request);

		//extract CSRF token
		final int csrf = result.indexOf("CSRFValidationCode");
		if ( csrf > -1 )
		{
			final int quote = result.indexOf('"', csrf);
			final int quote2 = result.indexOf('"', quote + 1);

			csrfToken = result.substring(quote + 1, quote2);
			logger.fine("CSRFToken set: " + csrfToken);
		}

		return result;
	}

	/**
	 * Creates an array of NameValuePairs and loads the default parameters at the end of the array while 
	 * the requested number of slots for customer parameters.
	 * @param numberOfCustomerParams
	 * @return
	 */
	public NameValuePair[] getParamTemplate( final int numberOfCustomerParams )
	{
		final NameValuePair[] pairs = new NameValuePair[numberOfCustomerParams + 4];
		int i = numberOfCustomerParams;
		pairs[i++] = new BasicNameValuePair("time", String.valueOf(System.currentTimeMillis()));
		pairs[i++] = new BasicNameValuePair("CSRFValidationCode", getCsrfToken());
		pairs[i++] = new BasicNameValuePair("ajaxrequest", "true");
		pairs[i++] = new BasicNameValuePair(":_CLIENT_TRANSFORMATION__", "true");
		return pairs;
	}

	public void checkGenericErrors( final String result ) throws ServiceException
	{
		if ( result.contains("window.location='loginframe") )
		{
			//system error sample: window.location='loginframe.jsp?locale=HU&amp;type=null';
			throw new ServiceException("System error occured."); //FIXME I18N all error message
		}
		else if ( result.length() < 100 )
		{
			throw new ServiceException("Datatype error occured.");
		}
		else if ( result.contains("Hiba oldal") )
		{
			//url:'/bfo.channel.web/dispatcher?_T_=/bfo/errortab.jsp&amp;_S_=bfo/error.jsp&amp;_F_=bfo.error&amp;errorid=MTMyNDE1Mzg4MDQ5NA',
			final int i1 = result.indexOf("errorid");
			if ( i1 >= 0 )
			{
				final String errorId = result.substring(result.indexOf('=', i1) + 1, result.indexOf('\'', i1));
				System.out.println("ErrorId=" + errorId);
				final String errorResult = doGet(FHBRequestFactory.getInstance().getAction("bfo/errortab.jsp",
						"bfo.error")
						+ "&errorid=" + errorId);
				debugFile("errorResult", errorResult);
			} //FIXME refine error handling
			throw new ServiceException("The request failed due to invalid data.");
		}
	}

	public void setCsrfToken( final String csrfToken )
	{
		this.csrfToken = csrfToken;
	}

	public String getCsrfToken()
	{
		if ( csrfToken == null )
			return "undefined";
		return csrfToken;
	}

	public static void main( final String[] args ) throws ServiceException
	{
		//init logger
		LoggerHelper.initLogger(Level.ALL);

		final Customer customer = new Customer();
		customer.setLoginId(args[0]);
		customer.setPassword(args[1]);

		//login
		final LoginService login = new FHBLoginService();
		login.setCustomer(customer);
		login.execute(null);

		final FHBSession fhb = (FHBSession) login.getSession();

		//...

		//logout
		final LogoutService logout = new FHBLogoutService();
		logout.execute(fhb);

		//init session
		//		final String init = session.doGet(FHBRequestFactory.URL_INIT);
		//		System.out.println("Init length: " + init.length());
		//		System.out.println("Session: " + session.getSessionId());
		//		session.debugFile("init", init);

		//download login
		//		final NameValuePair[] loginPageData = new NameValuePair[] {// 
		//		new BasicNameValuePair("flashenabled", "true"), //
		//				new BasicNameValuePair("scope_object", "__LOGIN__"),//
		//				new BasicNameValuePair("CSRFValidationCode", "undefined"),//
		//				new BasicNameValuePair("ajaxrequest", "true"), };
		//
		//		final String getLoginPage = session.doPost(
		//				FHBRequestFactory.getInstance().getAction(FHBRequestFactory.ACTION_LOGIN_PAGE, null), loginPageData);
		//		session.debugFile("getLoginPage", getLoginPage);

		//download channel menu - hatha...
		//		final NameValuePair[] channelMenuData = new NameValuePair[] {// 
		//		new BasicNameValuePair("flashenabled", "true"), //
		//				new BasicNameValuePair("CSRFValidationCode", "undefined"),//
		//				new BasicNameValuePair("ajaxrequest", "true"), };
		//
		//		final String channelMenuResult = session.doPost(
		//				FHBRequestFactory.getInstance().getAction("bfo/channel/web/menu/channelmenu.jsp", null),
		//				channelMenuData);
		//		session.debugFile("channelMenuResult", channelMenuResult);

		//welcome
		//		authoritydescription=undefined
		//		scope_object=page1317581432571202
		//		time=1317581432576
		//		CSRFValidationCode=ee1f10482c89b8c6b08302930643982
		//		ajaxrequest=true
		//		:__CLIENT_TRANSFORMATION__=true
		//		final NameValuePair[] welcdata = fhb.getParamTemplate(2);
		//		welcdata[0] = new BasicNameValuePair("authoritydescription", "undefined");
		//		welcdata[1] = new BasicNameValuePair("scope_object", "123");
		//
		//		final String welcresult = fhb.doPost(
		//				FHBRequestFactory.getInstance().getAction(FHBRequestFactory.ACTION_WELCOME,
		//						FHBRequestFactory.TYPE_CHECK_MULTICUSTOMER), welcdata);
		//		fhb.debugFile("welcresult", welcresult);
		//		fhb.checkGenericErrors(welcresult);

	}
}